var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
(function (factory) {
    if (typeof module === "object" && typeof module.exports === "object") {
        var v = factory(require, exports);
        if (v !== undefined) module.exports = v;
    }
    else if (typeof define === "function" && define.amd) {
        define(["require", "exports", "fs", "axios", "path", "fs-promise", "koa-router", "../lib/ContentTypeTool", "../lib/awaitWrap", "../com/configTool", "../lib/FSTool/index", "../lib/GISServer/Util/readFromDB", "../lib/GISServer/Util/readFromNet", "crypto", "../lib/GISServer/Util/saveToDB", "../lib/GISServer/Util/initDB", "../lib/GISServer/Util/readFromDisk"], factory);
    }
})(function (require, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    const fs_1 = __importDefault(require("fs"));
    const axios_1 = __importDefault(require("axios"));
    const path_1 = __importDefault(require("path"));
    const fs_promise_1 = __importDefault(require("fs-promise"));
    const koa_router_1 = __importDefault(require("koa-router"));
    const ContentTypeTool_1 = __importDefault(require("../lib/ContentTypeTool"));
    const awaitWrap_1 = __importDefault(require("../lib/awaitWrap"));
    const configTool_1 = __importDefault(require("../com/configTool"));
    const index_1 = __importDefault(require("../lib/FSTool/index"));
    const readFromDB_1 = __importDefault(require("../lib/GISServer/Util/readFromDB"));
    const readFromNet_1 = __importDefault(require("../lib/GISServer/Util/readFromNet"));
    const crypto_1 = __importDefault(require("crypto"));
    const saveToDB_1 = __importDefault(require("../lib/GISServer/Util/saveToDB"));
    const initDB_1 = __importDefault(require("../lib/GISServer/Util/initDB"));
    const readFromDisk_1 = __importDefault(require("../lib/GISServer/Util/readFromDisk"));
    const ProxyRoutes = new koa_router_1.default({ prefix: '/proxyServer' });
    function getRequestParams(ctx) {
        const protocol = ctx.params.protocol === 'http' ? 'http://' : 'https://';
        const ip = ctx.params.ip;
        const port = ctx.params.port;
        const relativeUrl = ctx.params.url;
        let originalUrl = `${protocol}${ip}:${port}/${relativeUrl}`;
        const originalParam = ctx.request.query;
        if (Object.keys(originalParam).length !== 0) {
            originalUrl += '?' + Object.keys(originalParam).map(key => {
                return `${key}=${originalParam[key]}`;
            }).join('&');
        }
        return { protocol, ip, port, relativeUrl, originalUrl };
    }
    ProxyRoutes
        .get('/no-cache/:protocol/:ip/:port/:url(.*)', async (ctx) => {
        const { originalUrl } = getRequestParams(ctx);
        if (originalUrl) {
            let [err, res] = await (0, awaitWrap_1.default)(axios_1.default.get(originalUrl, { responseType: 'arraybuffer' }));
            if (err) {
                ctx.status = 422;
                ctx.body = err;
            }
            else {
                for (const resKey in res.headers) {
                    ctx.set(resKey, res.headers[resKey]);
                }
                ctx.body = res.data;
            }
        }
    })
        .get('/auto-cache/:protocol/:ip/:port/:url(.*)', async (ctx) => {
        const { ip, port, relativeUrl, originalUrl } = getRequestParams(ctx);
        let fileSavePath = path_1.default.join(configTool_1.default.appBasePath, 'temp/fileOut', `${ctx.params.protocol}/${ip}/${port}/${relativeUrl}`);
        let fileDir = path_1.default.dirname(fileSavePath);
        if (originalUrl) {
            let [err, res] = await index_1.default.readFileAsync(fileSavePath);
            if (res) {
                let contentType = ContentTypeTool_1.default.getContentType(fileSavePath);
                ctx.set('Content-Type', contentType);
                ctx.body = res;
            }
            if (!res) {
                [err, res] = await (0, awaitWrap_1.default)(axios_1.default.get(originalUrl, { responseType: 'arraybuffer' }));
                if (err) {
                    ctx.status = 422;
                    ctx.body = err;
                }
                else {
                    for (const resKey in res.headers) {
                        ctx.set(resKey, res.headers[resKey]);
                    }
                    ctx.body = res.data;
                    if (configTool_1.default.preservableONFile()) {
                        if (!path_1.default.extname(fileSavePath)) {
                            fileSavePath += ContentTypeTool_1.default.getExt(res.headers['content-type']);
                        }
                        await fs_promise_1.default.ensureDir(fileDir);
                        fs_1.default.writeFileSync(fileSavePath, res.data);
                    }
                }
            }
        }
    })
        .get('/wall-Proxy/:protocol/:ip/:port/:url(.*)', async (ctx) => {
        const { ip, port, relativeUrl, originalUrl } = getRequestParams(ctx);
        const fileSavePath = path_1.default.join(configTool_1.default.appBasePath, 'temp/fileOut', `${ctx.params.protocol}/${ip}/${port}/${relativeUrl}`);
        const dbPath = '\\' + relativeUrl.replaceAll('/', '\\');
        if (originalUrl) {
            let err, buffer, dataSource;
            await (0, initDB_1.default)(ip);
            [err, buffer, dataSource] = await (0, readFromDB_1.default)({ DBName: ip, relativePath: dbPath });
            [err, buffer, dataSource] = await (0, readFromDisk_1.default)({ fileSavePath, err, buffer, dataSource });
            [err, buffer, dataSource] = await (0, readFromNet_1.default)({
                url: originalUrl, headers: {}, err, buffer, dataSource, option: {
                    proxy: {
                        protocol: 'http',
                        host: '127.0.0.1',
                        port: 7890
                    }
                }
            });
            if (buffer) {
                let contentType = ContentTypeTool_1.default.getContentType(fileSavePath);
                ctx.set('Content-Type', contentType);
                ctx.body = buffer;
                const md5Str = crypto_1.default.createHash('md5').update(buffer).digest('hex');
                if (md5Str) {
                    (0, saveToDB_1.default)({ DBName: ip, relativePath: dbPath, buffer }).then();
                }
            }
            else {
                ctx.status = 422;
                ctx.set('Content-Type', 'application/json;charset=utf-8');
                ctx.body = err;
                console.warn('代理 翻墙路径失败');
            }
        }
    });
    exports.default = ProxyRoutes;
});
